home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-17 | 41.8 KB | 1,397 lines | [TEXT/MPS ] |
- (************************************************************************
- * *
- * File: XTEFileIO.p *
- * *
- * Contains: Import/Export Code for use with XTEStyleSample *
- * *
- * Copyright: © 1989-91 by Claris Corporation, all rights reserved. *
- * *
- * Change History: *
- * *
- * 11/7/89 RJS First version *
- * 4/15/91 MJ Pascal version *
- * *
- ************************************************************************)
- UNIT XTEFileIO;
-
- INTERFACE
-
- USES
- MemTypes, QuickDraw, OSIntf, ToolIntf, PackIntf,
- Traps, MacPrint, Packages, TextEdit,
- XTNDInterface, XTNDTextTranslator, XTNDPictTranslator;
-
- CONST
- kNoText = '';
- kTabChar = '\t';
- kSpaceChar = ' ';
- kReturnChar = '\n';
- kRightBracket = ']';
- kFormulaText = '[Formula]';
- kNumberText = '[Number]';
- kCitationText = '[Citation]';
- kUnknownChar = '[Unknown Special Char';
- kUnknownFrame = '[Unknown Frame]';
- kMergeBreak = '\r[Merge Break]\r';
- kColumnBreak = '\r[Column Break]\r';
- kPageBreak = '\r[Page Break]\r';
- kSegmentBreak = '\r[Segment Break]\r';
- kSectionBreak = '\r[Section Break]\r';
- kPageNumText = '[Page Number]';
- kFootnoteText = '[Footnote #';
- kPictureText = '[Picture #';
-
- kNativeTypes = 1;
-
- {kMaxDocWidth is an arbitrary number used to specify the width of the TERec's
- destination rectangle so that word wrap and horizontal scrolling can be
- demonstrated.}
- kMaxDocWidth = 576;
-
- {kTextMargin is the number of pixels we leave blank at the edge of the window.}
- kTextMargin = 2;
-
- {kScrollBarAdjust and kScrollBarWidth are used in calculating
- values for control positioning and sizing.}
- kScrollbarWidth = 16;
- kScrollbarAdjust = kScrollbarWidth - 1;
-
- {kScrollTweek compensates for off-by-one requirements of the scrollbars
- to have borders coincide with the growbox.}
- kScrollTweek = 2;
-
- {kCrChar is used to match with a carriage return when calculating the
- number of lines in the TextEdit record. kDelChar is used to check for
- delete in keyDowns.}
- kCRChar = 13;
- kDelChar = 8;
-
- {kButtonScroll is how many pixels to scroll horizontally when the button part
- of the horizontal scrollbar is pressed.}
- kButtonScroll = 4;
-
- {kErrStrings is the resource ID for the error strings STR# resource.}
- kErrStrings = 128;
- kFileMessageID = 131;
- kTextRunsDispID = 134;
-
- { The following constants are all resource IDs, corresponding to their resources }
-
- rMenuBar = 128; { application's menu bar }
- rAboutAlert = 128; { about alert }
- rDocWindow = 128; { application's window }
-
- rVScroll = 128; { vertical scrollbar control }
- rHScroll = 129; { horizontal scrollbar control }
-
- rUserAlert = 129; { user error alert }
-
- { The following are indicies into STR# resources. }
- eWrongMachine = 1;
- eSmallSize = 2;
- eNoMemory = 3;
- eNoSpaceCut = 4;
- eNoCut = 5;
- eNoCopy = 6;
- eExceedPaste = 7;
- eNoSpacePaste = 8;
- eNoWindow = 9;
- eExceedChar = 10;
- eNoPaste = 11;
- eNoXTND = 12;
- eTranslatorLoad = 13;
- eImportOpenRes = 14;
- eFilterRead = 15;
- eImportOpen = 16;
- eFilterInit = 17;
- eDeleteFailed = 18;
- eCreateFail = 19;
- eOpenFail = 20;
-
- { QuickDraw text styles }
- kQDBold = 1;
- kQDItalic = 2;
- kQDUnderline = 4;
- kQDOutline = 8;
- kQDShadow = 16;
-
- TYPE
- {A DocumentRecord contains the WindowRecord for one of our document windows,
- as well as the TEHandle for the text we are editing. We have added fields to
- hold the ControlHandles to the vertical and horizontal scrollbars and to hold
- the address of the default clikLoop that gets attached to a TERec when you call
- TEAutoView. Other document fields can be added to this record as needed. For
- a similar example, see how the Window Manager and Dialog Manager add fields
- after the GrafPort.}
- DocumentRecord = RECORD
- docWindow : WindowRecord;
- docTE : TEHandle;
- docVScroll : ControlHandle;
- docHScroll : ControlHandle;
- docClik : ProcPtr;
- fileName : Str255;
- WDRefNum : INTEGER;
- myPrintRec : THPrint;
- END;
- DocumentPeek = ^DocumentRecord;
-
- (*----------------------------- Variables -----------------------------------*)
- VAR
- (*-------- External Variables ---------*)
- gMyFileType : ARRAY [1..kNativeTypes] OF TransDescribe;
- gFilterSelected : INTEGER;
- gTheReply : SFReply;
- gInitWndSize : Point; (*initial window size for saved files*)
- gTheActiveWindow : WindowPtr; (*pointer to front window*)
- WATCH : CursHandle;
-
- (*-------- text ---------*)
- gTextH : TEHandle; (*handle to text in front window*)
- gSelStart : INTEGER; (*start of initial selection range*)
- gSelEnd : INTEGER; (*end of initial selection range*)
- gIBeamHdl : CursHandle; (*handle to the I-beam cursor image*)
-
- (* The following globals are to support XTND import/export *)
- gShowTextRuns : Boolean;
- gBeforeDivider : Boolean;
- gXTNDAvail : Boolean;
-
- (*-------- Global Variables ---------*)
- gImportPB : ImportParmBlock;
- gPictImportPB : PictImportParmBlk;
- exportPB : ExportParmBlock;
- gExportTranslator,
- gImportTranslator : TransProcPtr;
- gParafmts : ARRAY [1..9] OF Fixed;
- gTabs : tabspecArray;
- gFNMarker : PACKED ARRAY [1..10] OF Byte;
- gNow : LongInt;
- gNumDocuments,
- gFootnoteCount : INTEGER;
- gFNStoryCount : INTEGER;
- gPictCount : INTEGER;
- gExportTextHandle : Handle;
-
- gExportTextLength : LongInt;
- gExportError : INTEGER;
- gExportRefNum : INTEGER;
- gExportTxtFace : INTEGER;
- gExportTxtSize : INTEGER;
- gExportTxtFont : INTEGER;
- gExportTxtColor : Byte;
- gExportTxtJust : INTEGER;
- Load_stored : INTEGER;
- Save_stored : INTEGER;
-
-
- (*--------------------------- Routines in this file ----------------------------*)
- PROCEDURE AlertUser( error, code : INTEGER );
- PROCEDURE AdjustHV( isVert : BOOLEAN; control : ControlHandle;
- docTE : TEHandle; canRedraw : BOOLEAN );
- PROCEDURE AdjustScrollValues( window : WindowPtr; canRedraw : BOOLEAN );
- PROCEDURE GetTERect( window : WindowPtr; VAR teRect : Rect);
- FUNCTION IsDAWindow( window : WindowPtr ) : BOOLEAN;
- FUNCTION IsAppWindow( window : WindowPtr ) : BOOLEAN;
- FUNCTION DoCloseWindow( window : WindowPtr ) : BOOLEAN;
- PROCEDURE DoSave(saveAs : Boolean);
- PROCEDURE DoOpen;
- PROCEDURE DoNew;
-
-
- (* ========================================================================≠============≠============== *)
- IMPLEMENTATION
-
- CONST
- {QUICKDRAWSTYLES = ORD(bold) + ORD(italic) + ORD(underline) + ORD(outline) + ORD(shadow); }
- QUICKDRAWSTYLES = 127;
-
-
- {$S Import}
- FUNCTION IsDAWindow( window : WindowPtr ) : BOOLEAN;
- { Check if a window belongs to a desk accessory. }
- BEGIN { IsDAWindow }
- IF window = NIL THEN
- IsDAWindow := FALSE
- ELSE { DA windows have negative windowKinds }
- IsDAWindow := WindowPeek( window )^.windowKind < 0;
- END; { IsDAWindow }
-
- FUNCTION IsAppWindow( window : WindowPtr ) : BOOLEAN;
- { Check if a window belongs to the application. }
- BEGIN { IsAppWindow }
- IF window = NIL THEN
- IsAppWindow := FALSE
- ELSE { application windows have non-negative windowKinds }
- IsAppWindow := WindowPeek( window )^.windowKind >= 0;
- END; { IsAppWindow }
-
- PROCEDURE AlertUser( error, code : INTEGER );
- { Display an alert that tells the user an error occurred, then exit the program }
- VAR
- itemHit : INTEGER;
- message, tempStr: Str255;
-
- BEGIN { AlertUser }
- SetCursor(arrow);
- GetIndString(message, kErrStrings, error);
- IF code <> 0 THEN BEGIN
- NumToString(code, tempStr);
- tempStr := concat('error number ', tempStr);
- END
- ELSE
- tempStr := '';
- ParamText(message, tempStr, '', '');
- itemHit := Alert( rUserAlert, NIL );
- END; { AlertUser }
-
- PROCEDURE AdjustHV( isVert : BOOLEAN; control : ControlHandle;
- docTE : TEHandle; canRedraw : BOOLEAN );
-
- {Calculate the new control maximum value and current value, whether it is the horizontal or
- vertical scrollbar. The vertical max is calculated by comparing the number of lines to the
- vertical size of the viewRect. The horizontal max is calculated by comparing the maximum document
- width to the width of the viewRect. The current values are set by comparing the offset between
- the view and destination rects. If necessary and we canRedraw, have the control be re-drawn by
- calling ShowControl.}
-
- {TEStyleSample-vertical max originally used line by line calculations-lineheight was a
- constant value so it was easy to figure out what the range should be and pin the value
- within range. Now we need to use max and min values in pixels rather than in nlines}
-
- VAR
- value, max : INTEGER;
- oldValue, oldMax : INTEGER;
-
- BEGIN { AdjustHV }
- oldValue := GetCtlValue( control );
- oldMax := GetCtlMax( control );
- IF isVert THEN BEGIN
- { new for TEStyleSample }
- max := ( TEGetHeight( docTE^^.nLines, 0, docTE ) ) -
- ( docTE^^.viewRect.bottom - docTE^^.viewRect.top );
- END ELSE
- max := kMaxDocWidth - (docTE^^.viewRect.right - docTE^^.viewRect.left );
-
- IF max < 0 THEN
- max := 0; { check for negative values }
- SetCtlMax( control, max );
- IF isVert THEN
- value := docTE^^.viewRect.top - docTE^^.destRect.top
- ELSE
- value := docTE^^.viewRect.left - docTE^^.destRect.left;
- IF value < 0 THEN
- value := 0
- ELSE IF value > max THEN
- value := max; { pin the value to within range }
- SetCtlValue( control, value );
- IF canRedraw & ( ( max <> oldMax ) | ( value <> oldValue ) ) THEN
- ShowControl( control ); { check to see if the control can be re-drawn }
- END; { AdjustHV }
-
- PROCEDURE GetTERect( window : WindowPtr; VAR teRect : Rect);
- { return a rectangle that is inset from the portRect by the size of
- the scrollbars and a little extra margin. }
- BEGIN { GetTERect }
- teRect := window^.portRect;
- InsetRect( teRect, kTextMargin, kTextMargin ); { adjust for margin }
- teRect.bottom := teRect.bottom - kScrollbarAdjust; { and for the scrollbars }
- teRect.right := teRect.right - kScrollbarAdjust;
- END; { GetTERect }
-
- FUNCTION DoCloseWindow( window : WindowPtr ) : BOOLEAN;
- { Close a window. This handles desk accessory and application windows. }
-
- BEGIN { DoCloseWindow }
- DoCloseWindow := TRUE;
- IF IsDAWindow( window ) THEN
- CloseDeskAcc( WindowPeek( window )^.windowKind )
- ELSE IF IsAppWindow( window ) THEN BEGIN
- WITH DocumentPeek( window )^ DO
- IF docTE <> NIL THEN
- TEDispose( docTE );
- CloseWindow( window );
- DisposPtr( Ptr( window ) );
- gNumDocuments := gNumDocuments - 1;
- END;
- END; { DoCloseWindow }
-
- PROCEDURE AdjustScrollValues( window : WindowPtr; canRedraw : BOOLEAN );
-
- { Simply call the common adjust routine for the vertical and horizontal scrollbars. }
-
- BEGIN { AdjustScrollValues }
- WITH DocumentPeek( window )^ DO BEGIN
- AdjustHV( TRUE, docVScroll, docTE, canRedraw );
- AdjustHV( FALSE, docHScroll, docTE, canRedraw );
- END; { with }
- END; { AdjustScrollValues }
-
- PROCEDURE AsmClikLoop; EXTERNAL;
- { A reference to our assembly language routine that gets attached to the clikLoop field of our TE record. }
- PROCEDURE DoNew;
- { Create a new document and window. }
-
- {Minor changes from TESample--TEStylNew instead of TENew-makes certain fields in
- the edit record (lineHeight, txFont, and txFace) have value of -1 and alloctes new
- tables to hold style information}
-
- VAR
- good, ignore : BOOLEAN;
- storage : Ptr;
- window : WindowPtr;
- destRect, viewRect : Rect;
-
- BEGIN { DoNew }
- storage := NewPtr( SIZEOF( DocumentRecord ) );
- IF storage <> NIL THEN BEGIN
- window := GetNewWindow( rDocWindow, storage, WindowPtr( -1 ) );
- IF window <> NIL THEN BEGIN
- gTheActiveWindow := window;
- gNumDocuments := gNumDocuments + 1;
- good := FALSE;
- SetPort( window );
- WITH window^, DocumentPeek( window )^ DO BEGIN
- GetTERect( window, viewRect );
- destRect := viewRect;
- destRect.right := destRect.left + kMaxDocWidth;
- docTE := TEStylNew( destRect, viewRect );
- { Use TEStylNew instead of TENew to initialize TERec correctly }
- IF docTE <> NIL THEN BEGIN
- good := TRUE; {if TENew succeeded, we have a good document}
- TEAutoView(TRUE, docTE);
- docClik := docTE^^.clikLoop;
- docTE^^.clikLoop := @AsmClikLoop;
- END;
- IF good THEN BEGIN
- myPrintRec := THPrint(NewHandle(sizeof(TPrint)));
- IF myPrintRec <> NIL THEN BEGIN
- PrOpen;
- PrintDefault(myPrintRec); (* load in default settings *)
- PrClose;
- END ELSE
- myPrintRec := NIL;
- END;
- IF good THEN BEGIN
- docVScroll := GetNewControl( rVScroll, window );
- good := ( docVScroll <> NIL );
- END; { if }
- IF good THEN BEGIN
- docHScroll := GetNewControl( rHScroll, window );
- good := ( docHScroll <> NIL );
- END; { if }
- IF good THEN BEGIN
- AdjustScrollValues( window, FALSE );
- ShowWindow( window ); { if the document is good, make the window visible }
- END ELSE BEGIN
- ignore := DoCloseWindow( window ); { otherwise regret we ever created it... }
- AlertUser( eNoWindow, 0 ); { and tell user }
- END { if }
- END; { with }
- END ELSE
- DisposPtr( storage ); { get rid of the storage if it is never used }
- END; { if }
- END; { DoNew }
-
-
- (* ------------------------------------------------------------------------+------------+-------------- *)
- PROCEDURE RGBFromXTND(VAR rgb: RGBColor; colorcode: INTEGER);
- BEGIN
- CASE colorcode OF
- 0: { WHITE }
- BEGIN
- rgb.red := 65535; rgb.green := 65535; rgb.blue := 65535
- END;
- 1: { BLACK }
- BEGIN
- rgb.red := 0; rgb.green := 0; rgb.blue := 0
- END;
- 2: { RED }
- BEGIN
- rgb.red := 65535; rgb.green := 0; rgb.blue := 0
- END;
- 3: { GREEN }
- BEGIN
- rgb.red := 0; rgb.blue := 0; rgb.green := 65535
- END;
- 4: { BLUE }
- BEGIN
- rgb.red := 0; rgb.green := 0; rgb.blue := 65535
- END;
- 5: { CYAN }
- BEGIN
- rgb.red := 0; rgb.green := 65535; rgb.blue := 65535
- END;
- 6: { MAGENTA }
- BEGIN
- rgb.red := 65535; rgb.blue := 65535; rgb.green := 0
- END;
- 7: { YELLOW }
- BEGIN
- rgb.red := 65535; rgb.green := 65535; rgb.blue := 0
- END
- END
- END;
-
-
- (* ------------------------------------------------------------------------+------------+-------------- *)
- FUNCTION RGBToXTND(theColor : RGBColor): INTEGER;
- (* ColorMap contains the conversion from QuickDraw color to our color id *)
- VAR
- r,g,b : INTEGER;
- colormap : ARRAY [0..7] OF INTEGER;
- BEGIN
-
- colormap[0] := 1;
- colormap[1] := 4;
- colormap[2] := 3;
- colormap[3] := 5;
- colormap[4] := 2;
- colormap[5] := 6;
- colormap[6] := 7;
- colormap[7] := 0;
-
- if BAND(theColor.red, $8000) <> 0 THEN
- r := 4
- ELSE
- r := 0;
-
- if BAND(theColor.green, $8000) <> 0 THEN
- g := 2
- ELSE
- g := 0;
-
- if BAND(theColor.blue, $8000) <> 0 THEN
- b := 1
- ELSE
- b := 0;
-
- RGBToXTND := colormap[r+g+b];
- END;
-
- (* ========================================================================≠============≠============== *)
- PROCEDURE ReadFile(pChosenOne: TransDescrPtr; theReply: SFReply);
- VAR
- window : WindowPtr;
- dummyptr : Ptr;
- TESlop : LONGINT;
- pm : pictMiscHdl;
- importPB : ImportParmBlock;
- hfsPB : ParamBlockRec;
- te : TEHandle;
- Parafmt : ARRAY [0..8] OF Fixed;
- Tabs : ARRAY [0..19] OF tabspec;
- MinusOne : Point;
- tempRect : Rect;
- Marker : ARRAY [0..9] OF Byte;
- fnum,
- resfnum,
- fserr : INTEGER;
- aPtr : IntegerPtr;
- count, textrun : LONGINT;
- newStyle : TextStyle;
- Buffer,
- theNumber : Str255;
- now : LONGINT;
- dummy : OSErr;
- handleLocked : Boolean;
- tempStyle : TEStyleHandle;
- state : SignedByte;
- BEGIN
- window := FrontWindow;
- TESlop := SIZEOF(TextStyle) + 500;
- fnum := 0;
- resfnum := 0;
- textrun := 0;
-
- SetCursor( GetCursor( watchCursor )^^ );
- SetWTitle(window, theReply.fName);
- fserr := XTNDLoadTranslator(pChosenOne, gImportTranslator);
- IF fserr <> noErr THEN
- BEGIN
- AlertUser(eTranslatorLoad,fserr);
- EXIT(ReadFile);
- END;
- MinusOne.v := -1;
- MinusOne.h := -1;
- te := DocumentPeek(window)^.docTE;
- importPB.TextBuffer := @Buffer;
- importPB.result := noErr;
- importPB.TextLength := 0;
- importPB.TxtFace := 0; { Plain }
- importPB.TxtSize := 0;
- importPB.TxtFont := helvetica;
- importPB.TxtColor := 0;
- importPB.TxtJust := 0; { Left }
- importPB.ParaFmts := @Parafmt;
- importPB.Tabs := @Tabs;
- importPB.NumCols := 1;
- importPB.CurrentStory := mainStory;
- importPB.MiscData := 0;
- importPB.StoryHeight := 0;
- importPB.DecimalChar := '.';
- importPB.AutoHyphenate := TRUE;
- importPB.PrintRecord := NIL;
- importPB.StartPageNum := 1;
- importPB.StartFootnoteNum := 1;
- Marker[0] := 0;
- importPB.FootnoteText := @Marker;
- importPB.RulerShowing := TRUE;
- importPB.DoubleSided := FALSE;
- importPB.TitlePage := FALSE;
- importPB.Endnotes := FALSE;
- importPB.ShowInvisibles := FALSE;
- importPB.ShowPageGuides := TRUE;
- importPB.ShowPictures := TRUE;
- importPB.AutoFootnotes := TRUE;
- importPB.PagePoint := MinusOne;
- importPB.DatePoint := MinusOne;
- importPB.TimePoint := MinusOne;
- importPB.SmartQuotes := TRUE;
- importPB.FractCharWidths := FALSE;
- importPB.HRes := 72;
- importPB.VRes := 72;
- importPB.TheReply := theReply;
- importPB.ThisTranslator := pChosenOne^;
- IF OpenRFPerm(theReply.fName, theReply.vRefNum, fsRdPerm) = -1 THEN
- BEGIN
- fserr := ResError;
- IF fserr <> eofErr THEN { No resource fork found }
- BEGIN
- AlertUser(eFilterRead,fserr);
- dummy := XTNDReleaseTranslator(pChosenOne);
- EXIT(ReadFile)
- END;
- UseResFile(pChosenOne^.ResRefNum); { For translators expecting to be the current resource file }
- END
- ELSE { If there is a resource fork for this file, read the resources }
- BEGIN
- resfnum := CurResFile;
- importPB.RefNum := resfnum;
- importPB.Directive := ImportGetResources;
- XTNDCallTranslator(@importPB, gImportTranslator);
- IF importPB.result <> noErr THEN
- BEGIN
- AlertUser(eFilterRead,importPB.result);
- CloseResFile(resfnum);
- dummy := XTNDReleaseTranslator(pChosenOne);
- EXIT(ReadFile)
- END
- END;
-
- { Open the file read only }
- fserr := 0;
- hfsPB.ioNamePtr := @theReply.fName;
- hfsPB.ioVRefNum := theReply.vRefNum;
- hfsPB.ioVersNum := 1;
- hfsPB.ioPermssn := fsRdPerm;
- hfsPB.ioMisc := Ptr(0);
- fserr := PBOpen(@hfsPB, FALSE);
- IF fserr <> noErr THEN
- BEGIN
- AlertUser(eFilterInit,fserr);
- CloseResFile(resfnum);
- dummy := XTNDReleaseTranslator(pChosenOne);
- EXIT(ReadFile)
- END;
- fnum := hfsPB.ioRefNum;
- importPB.RefNum := hfsPB.ioRefNum;
- importPB.Directive := ImportInitAll;
- XTNDCallTranslator(@importPB, gImportTranslator);
-
- { After completing the initialization, check for an error. If none, proceed. }
- IF importPB.result <> noErr THEN
- BEGIN
- AlertUser(eFilterInit,importPB.result);
- CloseResFile(resfnum);
- dummy := XTNDReleaseTranslator(pChosenOne);
- EXIT(ReadFile)
- END;
-
- { STAGE ONE - just read in the TEXT of the file. Ignore pictures }
-
- { Set starting place to be the MAIN body of text. }
- importPB.Directive := ImportInitMain;
- importPB.CurrentStory := mainStory;
- XTNDCallTranslator(@importPB, gImportTranslator);
- IF importPB.result = noErr THEN
- BEGIN
- SetRect(tempRect, 0, 0, 0, 0);
- ClipRect(tempRect); { close clip rect so text will not be drawn }
- GetDateTime(now);
- WHILE textrun < 30000 DO BEGIN
- importPB.Directive := ImportGetText;
- XTNDCallTranslator(@importPB, gImportTranslator);
-
- fserr := importPB.result;
- count := importPB.TextLength;
-
- IF (fserr <> noErr) OR ((importPB.Directive = ImportAcknowledge) AND (count <= 0)) THEN
- LEAVE;
- IF (count = 1) THEN BEGIN
- IF (ORD(Buffer[0]) < 32) THEN { Is it a special character? }
- CASE ORD(Buffer[0]) OF
- 2, { Page Number }
- 3, { Footnote reference }
- 5, { Footnote reference }
- 6, { Merge Break Char }
- 9, { Tab }
- 11, { Column Break }
- 12, { Page Break }
- 31: { Discretionary Hyphen }
- count := 0;
-
- 4: { Picture }
- { We have to dispose of the picture, even if we don't use it. }
- BEGIN
- pm := pictMiscHdl(importPB.MiscData);
- DisposHandle(Handle(pm^^.ThePicture));
- DisposHandle(Handle(pm));
- count := 0
- END;
-
- 21, { Short Date }
- 22, { Abbrev Date }
- 23, { Long date }
- 24, { Abbrev + day Date }
- 25: { Long + day Date }
- BEGIN
- IF importPB.MiscData <> 0 THEN
- IUDateString(importPB.MiscData, shortDate, theNumber)
- ELSE
- IUDateString(now, shortDate, theNumber);
- count := ORD(theNumber[0]);
- BlockMove(Ptr(ORD4(@theNumber) + 1), @Buffer, count);
- END;
-
- 26: { Time }
- BEGIN
- IF importPB.MiscData <> 0 THEN
- IUTimeString(importPB.MiscData, FALSE, theNumber)
- ELSE
- IUTimeString(now, FALSE, theNumber);
- count := ORD(theNumber[0]);
- BlockMove(Ptr(ORD4(@theNumber) + 1), @Buffer, count);
- END;
-
- 7: { Hard Return }
- Buffer[0] := CHR(13);
- END;
- END;
-
- IF count <> 0 THEN
- BEGIN
- { Boy, is TextEdit buggy ! We need to see if there is enough memory to add the textrun }
- dummyptr := NewPtr(count + TESlop);
- IF dummyptr = NIL THEN
- LEAVE
- ELSE
- DisposPtr(dummyptr);
-
- aPtr := IntegerPtr(@newStyle.tsFace); { Fix a bug in text edit }
- aPtr^ := 0;
-
- newStyle.tsFont := importPB.TxtFont;
- newStyle.tsFace := Style(BAND(importPB.TxtFace, QUICKDRAWSTYLES));
- newStyle.tsSize := importPB.TxtSize;
- RGBFromXTND(newStyle.tsColor, importPB.TxtColor);
- TESetStyle(doAll, newStyle, TRUE, te);
-
- { Now add the number of characters to the text edit handle in this window }
- TEInsert(@Buffer, count, te);
- IF MemError <> noErr THEN
- LEAVE;
-
- textrun := textrun + count;
- { NumToString(textrun, theNumber); { Used for debugging. Shows count in window title }
- { SetWTitle(window, theNumber); }
- END;
- END; {while}
-
- importPB.directive := importCloseMain;
- XTNDCallTranslator(@importPB, gImportTranslator);
- END;
-
- importPB.directive := importCloseAll;
- XTNDCallTranslator(@importPB, gImportTranslator);
-
- TECalText(te); { calc line starts in TERecord }
- TESetSelect(textrun, textrun, te); { Set insertion point }
- AdjustScrollValues(window, TRUE);
- SetRect(tempRect, -8000, -8000, 8000, 8000);
- ClipRect(tempRect); { open clip rect so text will be drawn }
-
- IF resfnum <> 0 THEN
- CloseResFile(resfnum);
- dummy := FSClose(fnum);
- dummy := XTNDReleaseTranslator(pChosenOne);
- END;
-
-
- (* ------------------------------------------------------------------------+------------+-------------- *)
- FUNCTION ReadPlainTextFile(theReply: SFReply; hTE: TEHandle): OSErr;
- (* Inserts the text from the TEXT document specified by the Standard
- File reply record theReply into the TextEdit record specified by hTE. The
- file is assumed to be initially closed. The file is opened, the text is
- inserted at the current insertion point, the window’s scrollbars are
- adjusted, and the file is closed. The user is alerted if an error occured.
- Note: This version of ReadPlainTextFile() is very simplistic. It reads
- the text into a block in the heap in one shot, then inserts it into the TE
- record. If the free memory isn’t at least twice the size of the text file
- ReadPlainTextFile() will fail. It also does not check the current size of
- the text of the TE record to guard against overflow. And it assumes that
- the specified file actually exists (which it may not if the Standard File
- reply record was not actually filled in by a Standard File routine). *)
- (* 04.19.91 m_o *)
- LABEL
- 86;
- VAR
- window: WindowPtr;
- err, dummy: OSErr;
- myPB: ParamBlockRec;
- hTx: Handle;
- BEGIN
- window := FrontWindow;
- SetCursor( GetCursor( watchCursor )^^ );
- SetWTitle(window, theReply.fName);
- hTx := NIL;
- { open the text file… }
- myPB.ioNamePtr := @theReply.fName;
- myPB.ioVRefNum := theReply.vRefNum;
- myPB.ioVersNum := 0;
- myPB.ioPermssn := fsRdPerm;
- myPB.ioMisc := NIL;
- err := PBOpen(@myPB, FALSE);
- IF err <> noErr THEN
- BEGIN
- AlertUser(eOpenFail,err);
- ReadPlainTextFile := err;
- EXIT(ReadPlainTextFile)
- END;
- { find out how much text in the file… }
- err := PBGetEOF(@myPB, FALSE);
- IF err <> noErr THEN
- BEGIN
- AlertUser(eOpenFail,err);
- ReadPlainTextFile := err;
- EXIT(ReadPlainTextFile)
- END;
- { get a buffer for the text… }
- hTx := NewHandle(LONGINT(myPB.ioMisc));
- IF hTx = NIL THEN
- BEGIN
- AlertUser(eCreateFail,0);
- GOTO 86
- END;
- MoveHHi(hTx);
- HLock(hTx);
- { read the file into the buffer… }
- myPB.ioBuffer := hTx^;
- myPB.ioReqCount := LONGINT(myPB.ioMisc);
- myPB.ioPosMode := fsFromStart;
- myPB.ioPosOffset := 0;
- IF PBRead(@myPB, FALSE) = noErr THEN
- BEGIN
- { insert text from buffer into TE record… }
- TEInsert(hTx^, myPB.ioActCount, hTE);
- { adjust window’s scrollbars… }
- AdjustScrollValues(hTE^^.inPort, TRUE)
- END;
- 86:
- IF hTx <> NIL THEN
- DisposHandle(hTx);
- dummy := PBClose(@myPB, FALSE);
- ReadPlainTextFile := err;
- END;
-
- FUNCTION SetStyleFrom(oldStyle : Style): INTEGER;
- VAR
- newStyle : INTEGER;
- BEGIN
- newStyle := 0; { Plain }
-
- IF bold IN oldStyle THEN
- newStyle := newStyle + kQDBold;
-
- IF italic IN oldStyle THEN
- newStyle := newStyle + kQDItalic;
-
- IF underline IN oldStyle THEN
- newStyle := newStyle + kQDUnderline;
-
- IF outline IN oldStyle THEN
- newStyle := newStyle + kQDOutline;
-
- IF shadow IN oldStyle THEN
- newStyle := newStyle + kQDShadow;
-
- SetStyleFrom := newStyle;
- END;
-
- (* ------------------------------------------------------------------------+------------+-------------- *)
- PROCEDURE SaveFile(pChosenOne: TransDescrPtr; theReply: SFReply);
- TYPE
- StyleRunPtr = ^StyleRun;
- VAR
- loop : LONGINT;
- fserr,
- fnum : INTEGER;
- Match : MatchInfo;
- exportPB : ExportParmBlock;
- runlength : LONGINT;
- textbuffer : Handle;
- textface,
- textsize,
- textfont,
- textjust,
- selStart,
- selEnd,
- myEnd : INTEGER;
- textcolor : SignedByte;
- Paragraph : ARRAY [1..9] OF Fixed;
- tabs : ARRAY [1..20] OF tabspec;
- MinusOne : Point ;
- tempRect : Rect;
- te : TEHandle;
- window : WindowPtr;
- start,
- stylerun : LONGINT;
- shndl : TEStyleHandle;
- dummy : OSErr;
- xerr,
- vRefNum : INTEGER;
- sruns : StyleRunPtr;
- theText : Handle;
- length,
- offset,
- textLength : LONGINT;
- Anentry : STElement;
- styleruns : STPtr;
- TextPtr : Ptr;
- thestyles : STHandle;
- BEGIN
- fserr := 0;
- window := FrontWindow;
- te := DocumentPeek(window)^.docTE;
- { In order to save the document, we have to parse our own document, and determine
- where the paragraph and style runs start and end. This is not a simple project in
- text edit! }
-
- { First, let's load the Translator, just so we know we can! }
- xerr := XTNDLoadTranslator(pChosenOne, gExportTranslator);
- IF xerr <> noErr THEN
- BEGIN
- AlertUser(eTranslatorLoad,xerr);
- EXIT(SaveFile)
- END;
-
- { Now, create the file so we can delete it. (Takes care of PMSP problem) }
- dummy := Create(theReply.fName, theReply.vRefNum, '????', '????');
- xerr := FSDelete(theReply.fName, theReply.vRefNum);
- IF xerr <> noErr THEN
- { Explain we couldn't delete the file - probably a write protect error }
- AlertUser(eDeleteFailed,xerr)
- ELSE
- BEGIN
- Match := pChosenOne^.Matches[0];
- fserr := Create(theReply.fName, theReply.vRefNum, Match.DocCreator, Match.DocType);
- IF fserr <> noErr THEN
- AlertUser(eCreateFail,fserr)
- ELSE
- BEGIN
- fserr := FSOpen(theReply.fName, theReply.vRefNum, fnum);
- IF fserr <> noErr THEN
- AlertUser(eOpenFail,fserr)
- END
- END;
- IF fserr <> noErr THEN
- BEGIN
- dummy := XTNDReleaseTranslator(pChosenOne);
- EXIT(SaveFile)
- END;
-
- Paragraph[1] := 0; { left indent offset }
- Paragraph[2] := 0; { first line indent offset }
- Paragraph[3] := 0; { right indent offset }
- Paragraph[4] := 0; { leading }
- Paragraph[5] := 0; { space before paragraph }
- Paragraph[6] := 0; { space after paragraph }
- Paragraph[7] := -1; { leading units (lines) }
- Paragraph[8] := 0; { space before units (points) }
- Paragraph[9] := 0; { space after units (points) }
- FOR loop := 1 TO 20 DO
- tabs[loop].TabIndent := -1;
-
- { Initialize the export Translator }
- SetRect(tempRect, 0, 0, 0, 0);
- MinusOne.v := -1;
- MinusOne.h := -1;
- textbuffer := NewHandle(0);
- IF textbuffer = NIL THEN
- BEGIN
- dummy := XTNDReleaseTranslator(pChosenOne);
- dummy := FSClose(fnum);
- EXIT(SaveFile)
- END;
-
- exportPB.ThePicture := NIL;
- exportPB.PictRect := tempRect;
- exportPB.FootnoteOffset := 0;
- exportPB.PagePoint := MinusOne;
- exportPB.DatePoint := MinusOne;
- exportPB.TimePoint := MinusOne;
-
- exportPB.TextBuffer := textbuffer;
- exportPB.TextLength := @runlength;
- exportPB.result := @fserr;
- exportPB.RefNum := @fnum;
- exportPB.TxtFace := @textface;
- exportPB.TxtSize := @textsize;
- exportPB.TxtFont := @textfont;
- exportPB.TxtColor := @textcolor;
- exportPB.TxtJust := @textjust;
- exportPB.ParaFmts := @Paragraph;
- exportPB.Tabs := @tabs;
- exportPB.FootnoteText := NIL;
-
- exportPB.topMargin := $00480000; { 1 inch margin }
- exportPB.bottomMargin := $00480000; { 1 inch margin }
- exportPB.leftMargin := $00480000; { 1 inch margin }
- exportPB.rightMargin := $00480000; { 1 inch margin }
- exportPB.Gutter := $000C0000; { 12 point column gap }
- exportPB.NumCols := 1;
- exportPB.StartPageNum := 1;
- exportPB.StartFootnoteNum := 1;
- exportPB.CurrentStory := mainStory;
- exportPB.RulerShowing := TRUE;
- exportPB.DoubleSided := FALSE;
- exportPB.TitlePage := FALSE;
- exportPB.Endnotes := FALSE;
- exportPB.ShowInvisibles := TRUE;
- exportPB.ShowPageGuides := TRUE;
- exportPB.ShowPictures := TRUE;
- exportPB.AutoFootnotes := TRUE;
- exportPB.SmartQuotes := TRUE;
- exportPB.FractCharWidths := TRUE;
- exportPB.HRes := 72;
- exportPB.VRes := 72;
- exportPB.WindowRect := tempRect;
-
- exportPB.HeaderStatus := 0;
- exportPB.FooterStatus := 0;
- myEnd := te^^.teLength;
- exportPB.TotalCharCount := te^^.teLength;
- exportPB.FootnotesExist := FALSE;
-
- exportPB.TheReply := theReply;
- exportPB.ThisTranslator := pChosenOne^;
-
- selStart := te^^.selStart;
- selEnd := te^^.selEnd;
- SetRect(tempRect, 0, 0, 0, 0);
- ClipRect(tempRect); { close clip rect so text will not be drawn }
-
- PrOpen;
- IF PrError = noErr THEN BEGIN
- exportPB.PrintRecord := THPrint(NewHandle(SIZEOF(TPrint)));
- IF exportPB.PrintRecord <> NIL THEN BEGIN
- PrintDefault(exportPB.PrintRecord);
- IF PrValidate(exportPB.printRecord) THEN
- { who cares? };
- END;
- PrClose;
- END
- ELSE
- exportPB.PrintRecord := NIL;
-
- exportPB.Directive := ExportInitAll;
- XTNDCallTranslator(@exportPB, gExportTranslator);
-
- { OK - let's open the main story }
-
- exportPB.Directive := ExportOpenMain;
- exportPB.CurrentStory := mainStory;
- XTNDCallTranslator(@exportPB, gExportTranslator);
-
- shndl := GetStylHandle(te); { There may not be _any_ style runs. }
- IF shndl <> NIL THEN
- BEGIN
- theText := Handle(TEGetText(te));
- textLength := te^^.teLength;
- HLock(theText);
- TextPtr := theText^;
- HLock(Handle(shndl));
- sruns := @shndl^^.runs;
- thestyles := shndl^^.styleTab;
- HLock(Handle(thestyles));
- styleruns := thestyles^;
- FOR stylerun := 0 TO shndl^^.nRuns - 1 DO
- BEGIN
- start := sruns^.startChar;
- length := StyleRunPtr(ORD4(sruns) + SIZEOF(StyleRun))^.startChar - start;
- IF length + start > textLength THEN
- length := textLength - start;
- offset := 0;
- runlength := 0;
- { Find the associated style entry }
- Anentry := styleruns^[sruns^.styleIndex];
- IF Anentry.stSize = 0 THEN
- Anentry.stSize := GetDefFontSize;
- textface := SetStyleFrom(Anentry.stFace);
- textsize := Anentry.stSize * 4; { multiply by four to simulate MacWrite II font size }
- textcolor := SignedByte(RGBToXTND(Anentry.stColor));
- textfont := Anentry.stFont;
- textjust := 0; { left; }
- WHILE offset + runlength < length DO
- BEGIN
- WHILE offset + runlength < length DO
- BEGIN
- IF Ptr(ORD4(TextPtr) + runlength)^ = 13 THEN
- BEGIN
- runlength := runlength + 1;
- LEAVE
- END;
- runlength := runlength + 1
- END;
- { Send runlength characters, starting at start + offset }
- SetHandleSize(textbuffer, runlength);
- { check to see if this fails }
- BlockMove(TextPtr, textbuffer^, runlength);
- exportPB.Directive := ExportWriteText;
- XTNDCallTranslator(@exportPB, gExportTranslator);
- TextPtr := Ptr(ORD4(TextPtr) + runlength);
- TESetSelect(start + offset, start + offset + runlength, te);
- offset := offset + runlength;
- runlength := 0;
- END;
- sruns := StyleRunPtr(ORD4(sruns) + SIZEOF(StyleRun))
- END;
-
- exportPB.Directive := ExportCloseMain;
- XTNDCallTranslator(@exportPB, gExportTranslator);
- END;
-
- exportPB.Directive := ExportCloseAll;
- XTNDCallTranslator(@exportPB, gExportTranslator);
-
- IF exportPB.PrintRecord <> NIL THEN
- DisposHandle(Handle(exportPB.PrintRecord));
- dummy := FSClose(fnum);
-
- { Write resource fork now. }
- dummy := GetVol(NIL, vRefNum);
- dummy := SetVol(NIL, theReply.vRefNum);
- CreateResFile(theReply.fName);
- fnum := OpenResFile(theReply.fName);
- exportPB.Directive := ExportWriteResources;
- XTNDCallTranslator(@exportPB, gExportTranslator);
- CloseResFile(fnum);
- dummy := SetVol(NIL, vRefNum);
-
- dummy := XTNDReleaseTranslator(pChosenOne);
-
- TESetSelect(selStart, selEnd, te); { Set insertion point }
- SetRect(tempRect, -8000, -8000, 8000, 8000);
- ClipRect(tempRect); { open clip rect so text will be drawn }
- END;
-
-
- (* ------------------------------------------------------------------------+------------+-------------- *)
- FUNCTION SavePlainTextFile(fileName: Str255; vRefNum: INTEGER; dirID: LONGINT;
- hTE: TEHandle; saveAll: BOOLEAN): OSErr;
- (* Saves the text from the TextEdit record specified by hTE to the file
- having the name fileName on the volume specified by vRefNum and in the
- directory specified by dirID. The file is assumed to be initially closed.
- It is opened, the text written out (replacing any previous contents of the
- file), and the file is closed. If saveAll is TRUE the entire text of the
- edit record is written out, otherwise only the text within the current
- selection is saved. The user is alerted if an error occured. *)
- (* 04.19.91 m_o *)
- LABEL
- 86;
- VAR
- err, dummy: OSErr;
- mfb: SignedByte;
- myHPB: HParamBlockRec;
- BEGIN
- { open the file… }
- myHPB.ioNamePtr := @fileName;
- myHPB.ioVRefNum := vRefNum;
- myHPB.ioVersNum := 0;
- myHPB.ioPermssn := fsRdWrPerm;
- myHPB.ioMisc := NIL;
- myHPB.ioDirID := dirID;
- err := PBHOpen(@myHPB, FALSE);
- IF err <> noErr THEN
- BEGIN
- AlertUser(eOpenFail,err);
- SavePlainTextFile := err;
- EXIT(SavePlainTextFile)
- END;
- { reset eof of file to zero… }
- myHPB.ioMisc := Ptr(0);
- err := PBSetEOF(ParmBlkPtr(@myHPB), FALSE);
- IF err <> noErr THEN
- BEGIN
- AlertUser(eOpenFail,err);
- GOTO 86
- END;
- { temporarily lock down text block of TE record;
- this is paranoia since PBWrite() is not supposed to move/purge memory… }
- MoveHHi(hTE^^.hText);
- mfb := HGetState(hTE^^.hText);
- HLock(hTE^^.hText);
- { write out TE text to file & reset lock-state of text block… }
- IF saveAll = TRUE THEN
- BEGIN
- myHPB.ioBuffer := hTE^^.hText^;
- myHPB.ioReqCount := hTE^^.teLength
- END
- ELSE
- BEGIN
- myHPB.ioBuffer := Ptr(ORD4(hTE^^.hText^) + hTE^^.selStart);
- myHPB.ioReqCount := hTE^^.selEnd - hTE^^.selStart
- END;
- myHPB.ioPosMode := fsFromStart;
- myHPB.ioPosOffset := 0;
- err := PBWrite(ParmBlkPtr(@myHPB), FALSE);
- HSetState(hTE^^.hText, mfb);
- 86:
- dummy := PBClose(ParmBlkPtr(@myHPB), FALSE);
- SavePlainTextFile := err;
- END;
-
-
- (* ------------------------------------------------------------------------+------------+-------------- *)
- FUNCTION SaveNewPlainTextFile(theReply: SFReply; fileType: OSType;
- hTE: TEHandle; saveAll: BOOLEAN; VAR vRefNum: INTEGER; VAR dirID: LONGINT): OSErr;
- (* Creates a new file and saves the text from the TextEdit record
- specified by hTE. The file is created with a creator of 'XTND' and filetype
- fileType. The name and location of the file is specified by the Standard
- File reply record *pTheReply. The directory ID and real volume reference
- number of the specified location are returned through the VAR parameters
- vRefNum and dDirID. Any existing file is first deleted. The file is closed
- after saving its contents. If saveAll is TRUE the entire text of the edit
- record is written out, otherwise only the text within the current selection
- is saved. If an error occured the user is alerted and the file is deleted. *)
- (* 04.19.91 m_o *)
- LABEL
- 86;
- VAR
- err, dummy: OSErr;
- myWDPB: WDPBRec;
- myHPB: HParamBlockRec;
- BEGIN
- { get the dirID and real vRefNum… }
- myWDPB.ioNamePtr := NIL;
- myWDPB.ioVRefNum := theReply.vRefNum;
- myWDPB.ioWDIndex := 0;
- myWDPB.ioWDProcID := 0;
- err := PBGetWDInfo(@myWDPB, FALSE);
- IF err <> noErr THEN
- BEGIN
- AlertUser(eCreateFail,err);
- SaveNewPlainTextFile := err;
- EXIT(SaveNewPlainTextFile)
- END;
- { delete file (if it already exists)… }
- myHPB.ioNamePtr := @theReply.fName;
- vRefNum := myWDPB.ioWDVRefNum;
- myHPB.ioVRefNum := myWDPB.ioWDVRefNum;
- myHPB.ioVersNum := 0;
- dirID := myWDPB.ioWDDirID;
- myHPB.ioDirID := myWDPB.ioWDDirID;
- err := PBHDelete(@myHPB, FALSE);
- IF (err <> noErr) & (err <> fnfErr) THEN
- BEGIN
- { …possibly locked or busy, or who knows what }
- AlertUser(eDeleteFailed,err);
- SaveNewPlainTextFile := err;
- EXIT(SaveNewPlainTextFile)
- END;
- { create the file… }
- err := PBHCreate(@myHPB, FALSE);
- IF err <> noErr THEN
- BEGIN
- AlertUser(eCreateFail,err);
- SaveNewPlainTextFile := err;
- EXIT(SaveNewPlainTextFile)
- END;
- { write text to file… }
- err := SavePlainTextFile(theReply.fName, myWDPB.ioWDVRefNum, myWDPB.ioWDDirID, hTE, saveAll);
- IF err <> noErr THEN
- GOTO 86;
- { set filetype & creator information… }
- myHPB.ioFDirIndex := 0;
- err := PBHGetFInfo(@myHPB, FALSE);
- IF err = noErr THEN
- BEGIN
- myHPB.ioDirID := myWDPB.ioWDDirID;
- myHPB.ioFlFndrInfo.fdType := fileType;
- myHPB.ioFlFndrInfo.fdCreator := 'XTND';
- err := PBHSetFInfo(@myHPB, FALSE)
- END;
- 86:
- IF err <> noErr THEN
- BEGIN
- AlertUser(eCreateFail,err);
- dummy := PBHDelete(@myHPB, FALSE)
- END
- END;
-
-
- (* ========================================================================≠============≠============== *)
- PROCEDURE DoOpen;
- (* Handler for the open command. Prompts the user for the file to open. If
- the user selects a file a new document window is created and the file is
- read in.
- If the XTND Library was successfully initialized its XTNDGetFile()
- routine is used to get the user’s document selection, otherwise the
- Standard File SFGetFile() routine is used. *)
- (* /04.19.91 m_o *)
- VAR
- getIt: BOOLEAN;
- myReply: SFReply;
- myXSFPB: SFParamBlock;
- myPrompt, myBTitle: Str255;
- where: Point;
- myTypes: SFTypeList;
- numDocuments: INTEGER;
- topDoc: DocumentPeek;
- err: OSErr;
- BEGIN
- IF gXTNDAvail = TRUE THEN
- BEGIN
- myXSFPB.AllowFlags := allowText;
- myXSFPB.NumStandard := kNativeTypes;
- myXSFPB.Standard := @gMyFileType;
- myXSFPB.ioResult := 0;
- myXSFPB.FileReply := @myReply;
- myXSFPB.XTNDDlogHook := NIL; { XTNDDlgHookProcPtr(MyDlg); }
- myXSFPB.CurrentMenuItem := Load_stored;
- myXSFPB.Where.v := 0;
- myXSFPB.Where.h := 0;
- myPrompt := 'Select a file to open';
- myXSFPB.Prompt := @myPrompt;
- myBTitle := 'Open';
- myXSFPB.ButtonTitle := @myBTitle;
- myXSFPB.DialogID := 0;
- myXSFPB.SFFilterProc := NIL;
- myXSFPB.ShowAllFiles := FALSE;
- myXSFPB.useMyTransList := FALSE;
- myXSFPB.myFileFilter := NIL;
- myXSFPB.Unused := 0;
- myReply.good := TRUE;
- getIt := XTNDGetFile(@myXSFPB);
- Load_stored := myXSFPB.CurrentMenuItem
- END
- ELSE
- BEGIN
- where.v := $40;
- where.h := $40;
- myTypes[1] := 'TEXT';
- SFGetFile(where, '', NIL, 1, myTypes, NIL, myReply);
- getIt := myReply.good
- END;
- IF getIt = TRUE THEN
- BEGIN
- numDocuments := gNumDocuments;
- DoNew;
- IF numDocuments <> gNumDocuments THEN { Did we open a new window? }
- IF (gXTNDAvail = TRUE) & (myXSFPB.chosenTranslator > myXSFPB.NumStandard) THEN
- ReadFile(myXSFPB.theChosenTranslator, myReply) { Read the file in using XTND. }
- ELSE
- BEGIN
- { Use the appropriate internally supported method of reading the file.
- While our application claims to support three (kNativeTypes) formats, they are
- all actually simple TEXT documents. }
- topDoc := DocumentPeek(FrontWindow);
- err := ReadPlainTextFile(myReply, topDoc^.docTE)
- END;
- END
- END;
-
-
- (* ------------------------------------------------------------------------+------------+-------------- *)
- PROCEDURE DoSave(saveAs: BOOLEAN);
- (* Handler for the Save and Save As commands. The parameter saveAs
- specifies the Save As command when it is TRUE.
- When handling a Save As command the user is prompted for a filename and
- location to save the document. The window title of the frontmost window is
- used as a default filename. If the user specifies a filename and location
- the file is created (deleting any previously existing one) and the contents
- of the frontmost document window are written to it.
- If the XTND Library was successfully initialized its XTNDPutFile()
- routine is used to get the user’s document selection, otherwise the
- Standard File SFGetFile() routine is used.
- Handling of the Save command is currently not implemented. If DoSave()
- is called with saveAs FALSE it will simply beep. *)
- (* /04.19.91 m_o *)
- VAR
- wTitle: Str255;
- putIt: BOOLEAN;
- myReply: SFReply;
- myXSFPB: SFParamBlock;
- window: WindowPtr;
- myPrompt, myBTitle: Str255;
- where: Point;
- vRefNum: INTEGER;
- dirID: LONGINT;
- err: OSErr;
- BEGIN
- window := FrontWindow;
- GetWTitle(window, wTitle);
- IF saveAs = FALSE THEN
- BEGIN
- { Handle a simple Save routine here. }
- SysBeep(1);
- EXIT(DoSave)
- END;
- IF gXTNDAvail = TRUE THEN
- BEGIN
- myXSFPB.AllowFlags := allowText + allowExport;
- myXSFPB.NumStandard := kNativeTypes;
- myXSFPB.Standard := @gMyFileType;
- myXSFPB.ioResult := 0;
- myXSFPB.FileReply := @myReply;
- myXSFPB.ApplicNativeType := 'TEXT';
- myXSFPB.XTNDDlogHook := NIL; { XTNDDlgHookProcPtr(MyDlg); }
- myXSFPB.CurrentSaveItem := Save_stored;
- myXSFPB.Where.v := 0;
- myXSFPB.Where.h := 0;
- myPrompt := 'Export File';
- myXSFPB.Prompt := @myPrompt;
- myBTitle := 'Save';
- myXSFPB.ButtonTitle := @myBTitle;
- myXSFPB.OrigName := @wTitle;
- myXSFPB.DialogID := 0;
- myXSFPB.SFFilterProc := NIL;
- myXSFPB.useMyTransList := FALSE;
- myXSFPB.myFileFilter := NIL;
- myXSFPB.Unused := 0;
- myReply.good := TRUE;
- putIt := XTNDPutFile(@myXSFPB);
- Save_stored := myXSFPB.CurrentSaveItem
- END
- ELSE
- BEGIN
- where.v := $40;
- where.h := $40;
- myPrompt := 'Save document as:';
- SFPutFile(where, myPrompt, wTitle, NIL, myReply);
- putIt := myReply.good
- END;
- IF putIt = TRUE THEN
- IF (gXTNDAvail = TRUE) & (myXSFPB.chosenTranslator > myXSFPB.NumStandard) THEN
- SaveFile(myXSFPB.theChosenTranslator, myReply) { Save the file using XTND. }
- ELSE
- { Use the appropriate internally supported method of saving the file.
- While our application claims to support three (kNativeTypes) formats, they are
- all actually simple TEXT documents. The only differentiation we make is
- the fileType we create the documents as. }
- err := SaveNewPlainTextFile(myReply, 'TEXT',
- DocumentPeek(window)^.docTE, {saveAll} TRUE, vRefNum, dirID)
- END;
-
-
- END.
-